﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Windows.Forms;
using DevComponents.DotNetBar;
using DevComponents.DotNetBar.Controls;
using DevComponents.Editors;
using Kugar.Core.WinForm.ControlExtMethod;
using Kugar.Core.WinForm.ExtMethod;
using Kugar.Core.ExtMethod;
using Kugar.ERPFramework.ClientBroker;
using Kugar.UI.WinForm;
using Kugar.Core.WinForm.ExtMethod;

namespace Kugar.ERPFramework.View.WinForm
{
    public partial class OrderEditorBase : ModuleDataEditorBase, IModuleForm
    {
        private ControlLayoutCollection panHeader = null;
        private ControlLayoutCollection panFoot = null;

        private Entity.EntityBase _currentViewModel = null;

#if DEBUG
        public OrderEditorBase():base()
#else
        protected OrderEditorBase()
#endif
        {
            InitializeComponent();

            dgMainData.AddRowIndex(true);

            if (ModuleControler !=null && base.ModuleControler is BLLInterface.IExecutable)
            {
                btnExecute.Visible = true;
            }

            if (ModuleControler !=null && base.ModuleControler is BLLInterface.IAuditable)
            {
                btnAudit.Visible = true;
            }

            HeaderFields=new ControlFieldsManager();
            FootFields=new ControlFieldsManager();
            BottomButtonList=new ButtonListManager(panButtonList);

            DetailFields=new DetailGridFieldsManager[1];
            DetailFields[0]=new DetailGridFieldsManager("",dgMainData);

            InitFields();
            ApplyFields();

            panHeader = new ControlLayoutCollection(this.HeaderFields, scDetailHeader.Panel1);
            panFoot = new ControlLayoutCollection(this.FootFields, scDetailData.Panel2);
        }

        public OrderEditorBase(Entity.EntityBase viewModel)
            : this()
        {
            _currentViewModel = viewModel;

            HeaderFields.BindObjectToField(viewModel);
            FootFields.BindObjectToField(viewModel);

            foreach (var detail in viewModel.Details)
            {
                var f = DetailFields.FirstOrDefault(x => x.DetailName == detail.Key);

                if (f!=null)
                {
                    f.BindObjectToField(detail.Value);
                }
            }
        }

        /// <summary>
        ///     顶部的字段管理
        /// </summary>
        [Browsable(false)]
        public ControlFieldsManager TopFields { protected set; get; }
        
        /// <summary>
        ///     报表头的字段管理
        /// </summary>
        [Browsable(false)]
        public ControlFieldsManager HeaderFields { protected set; get; }

        /// <summary>
        ///     报表明细的字段管理
        /// </summary>
        [Browsable(false)]
        public DetailGridFieldsManager[] DetailFields { protected set; get; }

        /// <summary>
        ///     报表页脚的字段管理
        /// </summary>
        [Browsable(false)]
        public ControlFieldsManager FootFields { protected set; get; }

        /// <summary>
        ///     底部的按钮栏
        /// </summary>
        [Browsable(false)]
        public ButtonListManager BottomButtonList { protected set; get; }

        [DefaultValue(true)]
        [Browsable(true)]
        public bool HeaderVisible
        {
            get { return panHeader.Visible; }
            set
            {
                panHeader.Visible=value;
                scDetailHeader.Panel1.Visible = value;
            }
        }

        [DefaultValue(true)]
        [Browsable(true)]
        public bool FootVisible
        {
            get { return panFoot.Visible; }
            set
            {
                panFoot.Visible = value;
                
                scDetailData.Panel2.Visible = value;
                
            }
        }

        /// <summary>
        ///     重载后添加窗体字段初始化代码
        /// </summary>
#if DEBUG
        protected virtual void InitFields()
        {
        }
#else
        protected abstract void InitFields();
#endif

        protected virtual void ApplyFields()
        {
            //ControlLayout(this.panHeader, this.HeaderFields.Select(x => x.Value).ToArray());

            foreach (var fieldsManager in DetailFields)
            {
                DataGridTableLayout(this.dgMainData, fieldsManager.Select(x => x.Value).ToArray());
            }

            //ControlLayout(this.panFoot, this.FootFields.Select(x => x.Value).ToArray());
        }


        protected virtual void DataGridTableLayout(DataGridView dataGrid, FieldConfig[] fields)
        {
            var editCtrlDefaultWidth = 80;

            foreach (var field in fields)
            {
                var config = (DetailColumnFieldConfig)field;

                config.ApplyToColumn();

                config.Column.Width = editCtrlDefaultWidth;
                config.Column.DefaultCellStyle = dgMainData.DefaultCellStyle;

                dataGrid.Columns.Add(config.Column);
            }
        }

        protected virtual void ControlLayout(Control parentControl, FieldConfig[] fields)
        {
            if (fields == null || fields.Length<=0)
            {
                return;
            }

            var currentX = 2;
            var currentY = 5;
            const  int editCtrlDefaultWidth = 80;
            const int editCtrlDefaultHeight = 20;
            const int ctrlSpacing = 5;
            const int groupSpacing = 10;



            foreach (var field in fields)
            {
                var ctrlField = (ControlFieldConfigBase)field;

                ctrlField.ApplyToControl();


                int labelWidth = 0;
                int labelHeight = 0;

                int editWidth = 0;
                int editHeight = 0;

                if (ctrlField.LabelCtrl != null)
                {
                    parentControl.Controls.Add(ctrlField.LabelCtrl);
                    var labelSize =ctrlField.GetLabelCtrlSize();
                    ctrlField.LabelCtrl.BackColor = parentControl.BackColor;
                    labelWidth = labelSize.Width + ctrlField.LabelCtrl.Margin.Right + ctrlSpacing;
                    labelHeight = labelSize.Height + ctrlField.LabelCtrl.Margin.Bottom + ctrlSpacing;

                }

                if (ctrlField.EditorCtrl != null)
                {
                    parentControl.Controls.Add(ctrlField.EditorCtrl);

                    ctrlField.EditorCtrl.Width = editCtrlDefaultWidth;
                    ctrlField.EditorCtrl.Height = editCtrlDefaultHeight;

                    editWidth = ctrlField.EditorCtrl.Width + ctrlField.EditorCtrl.Margin.Right + ctrlSpacing;
                    editHeight = ctrlField.EditorCtrl.Height;
                }


                if (currentX + labelWidth + editWidth > parentControl.ClientSize.Width)
                {
                    currentY += editCtrlDefaultHeight;
                }

                if (ctrlField.LabelCtrl != null)
                {
                    ctrlField.LabelCtrl.Left = currentX;
                    ctrlField.LabelCtrl.Top = currentY;
                }

                currentX += (labelWidth);

                if (ctrlField.EditorCtrl != null)
                {
                    ctrlField.EditorCtrl.Left = currentX;
                    ctrlField.EditorCtrl.Top = currentY;
                }

                currentX += editWidth;

                Center(ctrlField.EditorCtrl, ctrlField.LabelCtrl);

                currentX += groupSpacing;
            }
        }

        private void Center(Control baseCtrl, params Control[] targetCtrl)
        {
            var baseHeight = baseCtrl.Height;

            var graphics = Graphics.FromHwnd(baseCtrl.Handle);

            var baseRange = graphics.VisibleClipBounds;

            var baseLineY =(int) baseRange.Height/2 + baseCtrl.Top;

            graphics.Dispose();

            foreach (var control in targetCtrl)
            {
                var g = Graphics.FromHwnd(control.Handle);

                var r = g.VisibleClipBounds;
                
                g.Dispose();

                control.Top = control.Top + (baseLineY - ((int)r.Height/2 + control.Top));
            }
        }
    }

    public class ButtonListManager
    {
        private  Dictionary<string,ButtonInfo> _cache=new Dictionary<string, ButtonInfo>();
        private FlowLayoutPanel _panel = null;

        public ButtonListManager(FlowLayoutPanel panel)
        {
            _panel = panel;
        }

        public ButtonInfo Add(string buttonID, string text, Size size, EventHandler onClick)
        {
            var btn = new ButtonInfo(buttonID);
            btn.Text = text;
            btn.ButtonControl= btn.BuildButton();

            if (_cache.ContainsKey(buttonID))
            {
                throw new ArgumentOutOfRangeException("buttonID","已经存在相同ID的按钮");
            }

            _cache.Add(buttonID,btn);

            _panel.Controls.Add(btn.ButtonControl);

            return btn;
        }

        public class  ButtonInfo
        {
            private string _text = "";
            private bool _enable = true;
            private bool _visible = true;
            private Size _size;

            public ButtonInfo(string id)
            {
                ID = id;
            }

            public Control ButtonControl { internal set; get; }

            public string Text
            {
                set
                {
                    _text = value;
                    if (ButtonControl!=null)
                    {
                        ButtonControl.Text = value;
                    }
                }
                get { return _text; }
            }

            public bool Enabled
            {
                set
                {
                    _enable = value;
                    if (ButtonControl != null)
                    {
                        ButtonControl.Enabled = value;
                    }
                }
                get { return _enable; }
            }

            public bool Visible
            {
                set
                {
                    _visible = value;
                    if (ButtonControl != null)
                    {
                        ButtonControl.Visible = value;
                    }
                }
                get { return _visible; }
            }

            public string ID { private set; get; }

            public Size Size
            {
                set
                {
                    _size = value;
                    if (ButtonControl != null)
                    {
                        ButtonControl.Size = value;
                    }
                }
                get { return _size; }
            }

            public event EventHandler ButtonClick;

            internal ButtonX BuildButton()
            {
                var tempBtn = new ButtonX();

                tempBtn.AccessibleRole = AccessibleRole.PushButton;
                tempBtn.ColorTable = eButtonColor.OrangeWithBackground;
                tempBtn.Margin = new System.Windows.Forms.Padding(2);
                tempBtn.Shape = new RoundRectangleShapeDescriptor(7);
                tempBtn.Size = _size;
                tempBtn.Style = eDotNetBarStyle.StyleManagerControlled;
                tempBtn.Click += OnButtonClick;
                tempBtn.Text = _text;

                return tempBtn;
            }

            private void OnButtonClick(object sender, EventArgs e)
            {
                
            }
        }
    }






}
